/**
* \file		Case.h
* \brief	Définit la structure d'une Case
* \details	C'est ici que sont définis la structure des cases, ses
*		accesseurs, ses mutateurs.
*/

#ifndef CASE_H
#define CASE_H

#include "TabTerrains.h"
#include "Production.h"

/**
* \brief	Informations définissant l'entrepôt.
* \details	Ces informations sont les quantités des différentes matières
*               de base permettant au clan de perdurer et de prospérer.
*/

struct CaseStr
{
   Terrain *terrain;	/*!<Terrain de la Case : pointeur sur Terrain */
   Production *prod;	/*!<Type de production possible sur cette 				case : lien vers Production */
   char traversable;	/*<Si la case peut être traversée par un personnage :
			booléen grimé en caractère. Une case peut être non
			traversable soit parce que son terrain ne le permet
			pas, soit parce qu'il y a déjà quelqu'un sur la case
			*/
   int nbPers;		/*!<Nombre de personnes présentes sur la case :
			entier */
   unsigned int x;	/*!<Coordonnée x de la case */
   unsigned int y;	/*!<Coordonnée y de la case */
   unsigned int z;	/*!<Coordonnée z de la case */
   unsigned int xAdj;	/*!<Taille x du tableau des cases adjacentes */
   struct CaseStr **casesAdj;	/*!<Tableau de pointeurs vers les cases
				adjacentes à celle-ci. Tableau de une dimension
				stockant les pointeurs par colonne (c1l1, c1l2,
				c1l3, c2l1, c2l2, c2l3, c3l1... */
};

typedef struct CaseStr Case;


/*========================== Gestion de la mémoire ==========================*/
/**
* \brief	Initialise le contenu d'une Case donnée
* \details	Met à zéro les différents entiers et caractères de la
*		structure, fait pointer les pointeurs sur NULL
* \param	pcase		Pointeur sur une case donnée
*/
void initCase(Case *pcase, unsigned int xMax, unsigned int yMax, unsigned int zMax);

/**
* \brief	Libère une Case
* \details	Désalloue la mémoire originellement réservée pour le tableau
*		de pointeurs sur cases de la case et le fait pointer sur NULL
* \param	pcase		Case à libérer
*/
void libereCase(Case *pcase);

/*============================= Accesseurs =============================*/
/**
* \brief	Retourne le Terrain de la Case
* \param	pcase		Pointeur sur la Case
* \return	Un pointeur sur le Terrain de la Case
*/
Terrain *getTerrainCase(const Case *pcase);

/**
* \brief	Retourne la Production de la Case
* \param	pcase		Pointeur sur la Case
* \return	Un pointeur vers la production de la case donnée
*/
Production *getProdCase(const Case *pcase);

/**
* \brief	Retourne le nom de la Production d'une case. Si aucune
*		production, retourne NULL
* \param	pcase		Pointeur sur la Case
* \return	Une chaîne de caractères, le nom de la production de la case
*/
char *getNomProdCase(const Case *pcase);

/**
* \brief	Retourne le pourcentage de la Production d'une case. Si aucune
*		production, retourne -1
* \param	pcase		Pointeur sur la Case
* \return	Un entier
*/
int getPourcentageProdCase(const Case *pcase);

/**
* \brief	Retourne la vitesse de Production d'une case. Si aucune
*		production, retourne -1
* \param	pcase		Pointeur sur la Case
* \return	Un entier
*/
int getVitesseProdCase(const Case *pcase);

/**
* \brief	Retourne le nombre de personnages présents sur la case
* \param	pcase		Pointeur sur la Case
* \return	Un entier
*/
int getNbPersCase(const Case *pcase);

/**
* \brief	Retourne la valeur indiquant si la case est traversable
* \param	pcase		Pointeur sur la Case
* \return	Un caractère
*/
char getTraversableCase(const Case *pcase);

/**
* \brief	Retourne la coordonnée x de la case
* \param	pcase		Pointeur sur la Case
* \return	Un entier non signé
*/
unsigned int getXCase(const Case *pcase);

/**
* \brief	Retourne la coordonnée y de la case
* \param	pcase		Pointeur sur la Case
* \return	Un entier non signé
*/
unsigned int getYCase(const Case *pcase);

/**
* \brief	Retourne la coordonnée z de la case
* \param	pcase		Pointeur sur la Case
* \return	Un entier non signé
*/
unsigned int getZCase(const Case *pcase);

/**
* \brief	Retourne la taille xAdj du tableau des cases voisines
* \param	pcase		Pointeur sur la Case
* \return	Un entier non signé
*/
unsigned int getXAdjCase(const Case *pcase);

/**
* \brief	Retourne un pointeur sur le tableau des cases adjacentes à une
*		case dont on aura passé l'adresse
* \param	pcase		Pointeur sur la Case
* \return	Un tableau de pointeurs sur cases
*/
Case **getCasesAdjCase(const Case *pcase);

/*============================== Mutateurs ==============================*/
/**
* \brief	Remplace le Terrain de la case par un Terrain donné
* \param	pcase		Pointeur sur une case
* \param	pterrain	Pointeur sur le Terrain par lequel remplacer
*				celui de la case
*/
void setTerrainCase(Case *pcase, Terrain *pterrain);

/**
* \brief	Ajoute au nombre de personnages présents sur la case un
*		nombre de personnages donné
* \param	pcase		Pointeur sur une case
* \param	varNbPers	Entier
*/
void ajouteNbPersCase(Case *pcase, int varNbPers);

/**
* \brief	Remplace la valeur indiquant le nombre de personnes sur la
*		case par une valeur donnée
* \param	pcase		Pointeur sur une case
* \param	nouvNbPers	Entier
*/
void setNbPersCase(Case *pcase, int nouvNbPers);

/**
* \brief	Remplace la valeur indiquant si une case donnée est
*		traversable par une valeur donnée
* \param	pcase		Pointeur sur une case
* \param	nouvTrav	Caractère (parce qu'apparemment les booléens
*				ne sont pas connus de notre compilateur) ; 0
*				si pas traversable, 1 si traversable
*/
void setTraversableCase(Case *pcase, char nouvTrav);

/**
* \brief	Remplace la production de la case par une nouvelle Production
*		dont le nom aura été donné
* \details	Si un nom de production est donné, alloue une structure
*		Production dans le tas. Si la chaîne de caractère est en fait
*		en pointeur de valeur NULL, n'alloue pas de mémoire.
* \param	pcase		Pointeur sur une case
* \param	nomProd		Nom de la production : chaîne de caractères
*/
void setNouvProdCase(Case *pcase, char* nomProd);

/**
* \brief	Remplace le pourcentage de production de la case par une
*		valeur donnée additionnée à la valeur de base, si la case
*		donnée a bien une production
* \param	pcase		Pointeur sur une case
* \param	pourcent	Entier, nouvelle valeur
*/
void ajoutePourcentageProdCase(Case *pcase, int pourcent);

/**
* \brief	Remplace la vitesse de production de la case par une
*		valeur donnée additionnée à la valeur de base, si la case
*		donnée a bien une production
* \param	pcase		Pointeur sur une case
* \param	vitesse		Entier, nouvelle valeur
*/
void ajouteVitesseProdCase(Case *pcase, int vitesse);

/**
* \brief	Remplace la valeur de la coordonnée X de la case par une
*		valeur donnée après en avoir vérifié la validité
* \param	pcase		Pointeur sur une case
* \param	nouvX		Entier non signé, nouvelle valeur de X
* \param	Xmax		Entier non signé, valeur maximale possible
*				pour X
*/
void setXCase(Case *pcase, unsigned int nouvX, unsigned int Xmax);

/**
* \brief	Remplace la valeur de la coordonnée Y de la case par une
*		valeur donnée après en avoir vérifié la validité
* \param	pcase		Pointeur sur une case
* \param	nouvY		Entier non signé, nouvelle valeur de Y
* \param	Ymax		Entier non signé, valeur maximale possible
*				pour Y
*/
void setYCase(Case *pcase, unsigned int nouvY, unsigned int Ymax);

/**
* \brief	Remplace la valeur de la coordonnée Z de la case par une
*		valeur donnée après en avoir vérifié la validité
* \param	pcase		Pointeur sur une case
* \param	nouvZ		Entier non signé, nouvelle valeur de Z
* \param	Zmax		Entier non signé, valeur maximale possible
*				pour Z
*/
void setZCase(Case *pcase, unsigned int nouvZ, unsigned int Zmax);

/**
* \brief	Remplace la valeur de la taille xAdj de la case par une
*		valeur donnée
* \param	pcase		Pointeur sur une case
* \param	nouvX		Entier non signé, nouvelle valeur de xAdj
*/
void setXAdjCase(Case *pcase, unsigned int nouvXAdj);

/**
* \brief	Remplace la valeur de la coordonnée X de la case par une
*		valeur donnée après en avoir vérifié la validité
* \param	pcase		Pointeur sur une case
* \param	i		Numéro de la case (la numérotation commençant à
*				zéro) du tableau des cases adjacentes à donner
* \param	pcaseAdj	pointeur sur case adjacente
*/
void setIemeCaseAdjCase(Case *pcase, unsigned int i, Case *pcaseAdj);

/*========================== Autres fonctions ==========================*/
/**
* \brief	Enlève la production d'une case donnée
* \details	Désaloue la mémoire allouée à la production si besoin est, et
*		fait pointer le pointeur vers production sur NULL
* \param	pcase		Pointeur sur une case
*/
void enleveProdCase(Case *pcase);

/*========================== Fonction de Test ==========================*/
/**
* \brief	Teste les différentes fonctions du module Case
* \details	Teste les différentes fonctions du module Case en les
*		utilisant avec diverses valeurs plus ou moins probables
*/
void testCase();

#endif
